package com.derbysoft.synxisadapter.webservice.impl;

import com.derbysoft.synxisadapter.commons.dto.synxis.OTAHotelAvailRQ;
import com.derbysoft.synxisadapter.commons.dto.synxis.OTAHotelAvailRS;
import com.derbysoft.synxisadapter.commons.log.LogDetailPair;
import com.derbysoft.synxisadapter.commons.log.TransactionLogger;
import com.derbysoft.synxisadapter.commons.model.Channel;
import com.derbysoft.synxisadapter.commons.model.Direction;
import com.derbysoft.synxisadapter.commons.utils.ErrorMessageUtils;
import com.derbysoft.synxisadapter.webservice.SynXisWebService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.ws.client.core.WebServiceTemplate;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Component("getAvailWebService")
public class GetAvailWebServiceImpl extends AbstractSynXisWebService<OTAHotelAvailRQ, OTAHotelAvailRS>
        implements SynXisWebService<OTAHotelAvailRQ, OTAHotelAvailRS> {

    @Autowired
    @Qualifier("availWebServiceTemplate")
    protected WebServiceTemplate webServiceTemplate;

    @Override
    public OTAHotelAvailRS invoke(OTAHotelAvailRQ request, Channel channel) throws Exception {
        Set<LogDetailPair> logDetails = TransactionLogger.getLogDetails().get();
        if (logDetails == null) {
            logDetails = new HashSet<LogDetailPair>();
            TransactionLogger.getLogDetails().set(logDetails);
        }
        logDetails.add(LogDetailPair.build(request, Direction.TO_HOTEL));
        try {
            OTAHotelAvailRS otaHotelAvailRS = invoke(webServiceTemplate, request, channel);
            logDetails.add(LogDetailPair.build(otaHotelAvailRS, Direction.FROM_HOTEL));
            return otaHotelAvailRS;
        } catch (Exception ex) {
            TransactionLogger.getTransactionLogger().get().setError(true);
            logDetails.add(LogDetailPair.build(ErrorMessageUtils.buildErrorMessage(ex), Direction.FROM_HOTEL));
            throw new Exception(ex);
        }
    }

    @Override
    public List<ResponsePair<OTAHotelAvailRQ, OTAHotelAvailRS>> batchInvoke(List<OTAHotelAvailRQ> requests, Channel channel) throws Exception {
        Set<LogDetailPair> logDetails = TransactionLogger.getLogDetails().get();
        if (logDetails == null) {
            logDetails = new HashSet<LogDetailPair>();
            TransactionLogger.getLogDetails().set(logDetails);
        }
        logDetails.add(LogDetailPair.build(requests, Direction.TO_HOTEL));
        try {
            List<ResponsePair<OTAHotelAvailRQ, OTAHotelAvailRS>> responsePairs = doBatchInvoke(webServiceTemplate, requests, channel);
            List<OTAHotelAvailRS> otaHotelAvailRSes = new ArrayList<OTAHotelAvailRS>();
            for (ResponsePair<OTAHotelAvailRQ, OTAHotelAvailRS> responsePair : responsePairs) {
                otaHotelAvailRSes.add(responsePair.getResponse());
            }
            logDetails.add(LogDetailPair.build(otaHotelAvailRSes, Direction.FROM_HOTEL));
            return responsePairs;
        } catch (Exception ex) {
            TransactionLogger.getTransactionLogger().get().setError(true);
            logDetails.add(LogDetailPair.build(ErrorMessageUtils.buildErrorMessage(ex), Direction.FROM_HOTEL));
            throw new Exception(ex);
        }
    }

    public void setWebServiceTemplate(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
    }
}
